using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Microsoft.VSPowerToys.PackInstallerDataModel;

namespace Microsoft.VSPowerToys.PackInstaller
{
    public partial class SortListControl : UserControl
    {
        /// <summary>
        /// Raised when user selects a new tag from the list
        /// </summary>
        public event EventHandler<SortMethodSelectedEventArgs> SortMethodSelected;

        private SortedDictionary<ToolItem.SortByField, SortItemControl> sortControls;
        private SortItemControl currentlySelectedSortMethod;

        /// <summary>
        /// Property for which tag is currently selected in the list.
        /// </summary>
        public ToolItem.SortByField CurrentlySelectedSortMethod
        {
            get 
            {
                if(currentlySelectedSortMethod != null)
                {
                    return currentlySelectedSortMethod.SortMethodType;
                }
                else
                {
                    return ToolItem.SortByField.None;
                }
            }
        }

        /// <summary>
        /// Gets the sort order selected by the user
        /// </summary>
        public SortOrder CurrentSortOrder
        {
            get { return this.currentlySelectedSortMethod.CurrentSortOrder; }
        }

        /// <summary>
        /// Constructor, sets up the dictionary of tag text to tag control.
        /// </summary>
        public SortListControl()
        {
            sortControls = new SortedDictionary<ToolItem.SortByField, SortItemControl>();
            InitializeComponent();
        }

        /// <summary>
        /// Gets a control created for each tag, and then adds those controls to the control array.  We do this
        /// as a two step process so we get the tags all sorted before they get added to the control array.
        /// </summary>
        public void AddSortMethods(Dictionary<string, ToolItem.SortByField> sortMethods)
        {
            foreach (KeyValuePair<string, ToolItem.SortByField> sortMethod in sortMethods)
            {
                AddSortControl(sortMethod);
            }

            int tabIndex = 0;
            foreach (KeyValuePair<ToolItem.SortByField, SortItemControl> keyValuePair in this.sortControls)
            {
                this.Controls.Add(keyValuePair.Value);
                keyValuePair.Value.TabIndex = tabIndex;
                keyValuePair.Value.TabStop = false;
                keyValuePair.Value.BringToFront();
                tabIndex++;
            }
        }

        /// <summary>
        /// Clears out the controls from both the dictionary and the control array.
        /// </summary>
        public void ClearSortMethods()
        {
            this.sortControls.Clear();
            this.Controls.Clear();
        }

        public void SetSortMethod(ToolItem.SortByField whichMethod, SortOrder whatOrder)
        {
            if (this.sortControls.ContainsKey(whichMethod))
            {
                this.sortControls[whichMethod].SelectSortMethod(whatOrder);
            }
        }

        /// <summary>
        /// Unselects the current tag by setting it's state to none, and then clearing the reference.
        /// </summary>
        public void ClearSortMethodSelection()
        {
            if (this.currentlySelectedSortMethod != null)
            {
                this.currentlySelectedSortMethod.CurrentSortMethodState = SortItemControl.SortMethodState.None;
                this.currentlySelectedSortMethod = null;
            }
        }

        /// <summary>
        /// Adds a new tag if we don't have one for the string we're adding already.
        /// If we do have the tag in the list already then we increment its tag count.
        /// </summary>
        /// <param name="tag" />
        private void AddSortControl(KeyValuePair<string, ToolItem.SortByField> sortMethod)
        {
            if (!this.sortControls.ContainsKey(sortMethod.Value))
            {
                SortItemControl newControl = new SortItemControl(sortMethod.Key, sortMethod.Value);
                newControl.Name = sortMethod.Key + Strings.SortControlName;
                newControl.Dock = DockStyle.Top;
                newControl.SortMethodSelected += new EventHandler<SortMethodSelectedEventArgs>(sortControl_SortMethodSelected);
                this.sortControls.Add(sortMethod.Value, newControl);
            }
        }

        /// <summary>
        /// event raised when one of the tags gets selected.  First thing we have to do
        /// is unselect the current tag, then save which tag is now selected.
        /// And then propagate the message up.
        /// </summary>
        /// <param name="sender" />
        /// <param name="e" />
        private void sortControl_SortMethodSelected(object sender, SortMethodSelectedEventArgs e)
        {
            SortItemControl newSortMethod = sender as SortItemControl;
            if (this.currentlySelectedSortMethod != null && ((newSortMethod != null) && (newSortMethod != this.currentlySelectedSortMethod)))
            {
                this.currentlySelectedSortMethod.CurrentSortMethodState = SortItemControl.SortMethodState.None;
            }

            this.currentlySelectedSortMethod = newSortMethod;

            if (this.SortMethodSelected != null)
            {
                this.SortMethodSelected(this, e);
            }
        }
    }
}
